package view.actionListeners;

import java.awt.Color;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

import javax.swing.JButton;

import view.ChessGUI;
import view.ChessGUI.ClickedPiece; 
import controller.Controller;
import controller.Movement;

/**
 * Class implements an action listener for board button, used in two players game mode
 */
public class PlayerListener implements ActionListener {
	
	private int boardSize; // chess board's size
	private Color mark; // color to mark reachable position	
	private List<JButton> boardButtons; // list of all board buttons	
	private ClickedPiece lastToBeClicked; // last piece the user clicked on	
	private ChessGUI displayManager; // object to manage board display
	private Controller gameManager; // system's game manager
	private AtomicBoolean isEnabled; // used to switch button on or off
	
	/**
	 * Marks all board buttons that the piece at the clicked button can reach to
	 * @param row- row index of clicked button
	 * @param col- column index of clicked button
	 */
	private void findMoves(int row, int col) {

		// get reachable positions from clicked button
		List<Point> moveList = gameManager.getSafeDestinations(new Point(row, col));

		
		// check if there are any reachable positions
		if (moveList.isEmpty()) {
			// no reachable positions
			return;
		}
		
		// update last-to-be-clicked button's position
		lastToBeClicked.setPosition(row, col);

		// refresh board display 
//		displayManager.refreshBoardDisplay(lastToBeClicked.getMoveList()); // TODO used to be activated
		displayManager.setDefaultColor(lastToBeClicked.getMoveList());
		
		// update last-to-be-clicked button's move list
		lastToBeClicked.getMoveList().clear();
		lastToBeClicked.getMoveList().addAll(moveList);
		
		// mark all reachable positions
		for (Point currPosition : moveList) {
			
			// get button matching current position on board			
			JButton currBtn = boardButtons.get((currPosition.x-1)*boardSize + currPosition.y-1); // convert row-column index to linear index
			// mark button
			currBtn.setBackground(mark);
		}
	}
	
	/**
	 * Returns position of the clicked board button
	 * @param event- action event object
	 * @return position of clicked board button
	 */
	private Point getButtonPosition(ActionEvent event) {
		// get clicked button's index
		String command = event.getActionCommand();
		int index = Integer.parseInt(command);
		
		// calculate board entry of clicked button
		int row = (index / boardSize) + 1;
		int col = (index % boardSize) + 1;
		
		// return button position
		return new Point(row, col);
	}

	private boolean canMove(Point clickedPosition) {
		
		// check if clicked button is a destination for last-to-be-clicked button
		if (!lastToBeClicked.getMoveList().contains(clickedPosition)) {
			
			// cannot move to clicked piece 
			return false;
		}
		
		// can move to clicked piece
		return true;
	}

	public PlayerListener(int boardSize, Color mark, ChessGUI displayManager, Controller gameManager, ClickedPiece lastToBeClicked, List<JButton> boardButtons, AtomicBoolean isEnabled) {
		
		// set members according to given values
		this.boardSize = boardSize;
		this.mark = mark;
		this.displayManager = displayManager;
		this.gameManager = gameManager;
		this.lastToBeClicked = lastToBeClicked;
		this.boardButtons = boardButtons;
		this.isEnabled = isEnabled;
	}
	
	/**
	 * When button is clicked, asks game manager for list of reachable positions of piece at clicked button.
	 * If list is empty, nothing is done.
	 * Otherwise, last-to-be-clicked button is updated to this clicked button and piece's reachable positions are marked
	 */
	@Override
	public void actionPerformed(ActionEvent event) {
		
		// check is display is enabled
		if (!isEnabled.get()) {
			
			// display is disabled
			return;
		}
		
		// get clicked button position on board
		Point clickedPosition = getButtonPosition(event); 
		
		// check if should make move
		if (canMove(clickedPosition)) {
			
			displayManager.selectedMove = new Movement(lastToBeClicked.getPosition(), clickedPosition);
			displayManager.humanMovementDone.set(true);
			
			// refresh board display
			lastToBeClicked.getMoveList().add(lastToBeClicked.getPosition());
//			displayManager.refreshBoardDisplay(lastToBeClicked.getMoveList()); // TODO used to be activated
			displayManager.setDefaultColor(lastToBeClicked.getMoveList());

			// update last-to-be-clicked button's move list
			lastToBeClicked.getMoveList().clear();
			
		} else {
			// no move to make
			findMoves(clickedPosition.x, clickedPosition.y);
		}
		
		return;
	}
}